﻿using Core.Formats;
using Core.ObjectOperate.ReflectionImpl;
using Core.ReadWriter;
using System;
using System.IO;

namespace Core.Tools
{
    public class Logs
    {

        private static object InstanceLock = new object();
        private static Logs Instance;

        public static DirectoryInfo LogsDirectory;
        public static IDocumentFormat Format;

        static Logs()
        {
            Format = new JsonFormat();
        }

        private static bool Initialize()
        {
            if (LogsDirectory == null)
            {
                return false;
            }

            if (Format == null)
            {
                throw new NullReferenceException("Format");
            }

            if (Instance == null)
            {
                SetLogs(typeof(Logs));
            }

            return true;
        }

        public static void Log(string Text)
        {
            if (Initialize())
            {
                var Writer = Instance.Writer;

                Writer.WriteLine(Text);

                Instance.CloseWriter(Writer);
            }
        }

        public static void Exception(Exception e)
        {
            if (Initialize())
            {
                var Writer = Instance.Writer;

                Format.Encode(BaseReadWriter.Create(e), Writer);

                Instance.CloseWriter(Writer);
            }
        }


        public static void SetLogs(Type LogsType)
        {
            if (LogsType == null)
            {
                throw new NullReferenceException("LogsType");
            }

            if (!(typeof(Logs).IsAssignableFrom(LogsType)))
            {
                throw new Exception("“LogsType” 必须继承 Logs 类！");
            }

            var NPConstructorInfo = LogsType.GetConstructor(Type.EmptyTypes);

            if (NPConstructorInfo == null)
            {
                throw new Exception("“LogsType” 没有可访问的无参构造函数！");
            }

            Instance = (Logs)ConstructorInfo.Create(NPConstructorInfo).New(null);
        }

        public Logs()
        {
        }

        public virtual TextWriter Writer
        {
            get
            {
                if (LogsDirectory == null)
                {
                    return null;
                }

                DirectoryInfo CurrentTimeDirctory = new DirectoryInfo(Path.Combine(LogsDirectory.FullName, DateTime.Now.ToString("yyyy-MM-dd")));

                if (!CurrentTimeDirctory.Exists)
                {
                    IOHelper.CreateDirectory(CurrentTimeDirctory);
                }

                FileStream LogFileStream = new FileStream(Path.Combine(CurrentTimeDirctory.FullName, Guid.NewGuid().ToString("N") + ".log"), FileMode.Create, FileAccess.ReadWrite);

                return new StreamWriter(LogFileStream);
            }
        }

        protected virtual void CloseWriter(TextWriter Writer)
        {
            Writer.Close();
        }
    }
}
